#ifndef __CAMERA_HH__
#define __CAMERA_HH__

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>

namespace opengl
{

// 摄像机移动方向
enum CameraMovement {
    FORWARD,
    BACKWARD,
    LEFT,
    RIGHT
};

// 摄像机常量
const float YAW         = -90.0f;
const float PITCH       =  0.0f;
const float SPEED       =  4.0f;
const float SENSITIVITY =  0.1f;

// 摄像机类
class Camera
{
public:
    // 使用向量构造
    Camera(const glm::vec3& position = glm::vec3(0.0f, 0.0f, 0.0f), const glm::vec3& up = glm::vec3(0.0f, 1.0f, 0.0f), float yaw = YAW, float pitch = PITCH);
    
    // 返回 lookAd 矩阵
    glm::mat4 viewMat() const
    { return glm::lookAt(this->_position, this->_position + this->_front, this->_up); }

    // 水平移动
    glm::vec3 horizontalMove(CameraMovement direction, float deltaTime, float raduis);

    // 鼠标控制
    void changeSight(float xoffset, float yoffset, bool constrainPitch = true);

    // 设置到下一关位置
    void updatePosition()
    { this->_position = this->_nextPosition; }

    // 上升
    void rise(float deltaTime)
    { this->_position.y += this->_moveSpeed * deltaTime; }

    void drop(float deltaTime)
    { this->_position.y -= this->_moveSpeed * deltaTime; }

private:
    // 更新摄像机状态
    void update();

protected:
    // 摄像机属性
    glm::vec3 _position;
    glm::vec3 _nextPosition;
    glm::vec3 _front;
    glm::vec3 _up;
    glm::vec3 _right;
    glm::vec3 _worldUp;
    
    // 角度
    float _yaw;
    float _pitch;
    // 摄像机选项
    float _moveSpeed;
    float _moveSensitivity;

public:
    // 属性
    glm::vec3& position()
    { return this->_position; }

    const glm::vec3& position() const
    { return this->_position; }

    glm::vec3& front()
    { return this->_front; } 

    const glm::vec3& front() const
    { return this->_front; } 
    
    glm::vec3& right()
    { return this->_right; } 

    const glm::vec3& right() const
    { return this->_right; } 
};

}

#endif